<?php
namespace App\Models\Traits;

use Carbon\Carbon;
use Redis;

trait LastActivedAtHelper
{
    //缓存相关
    protected $hash_prefix = 'larabbs_last_actived_at_';
    protected $field_prefix = 'user_';

    public function recordLastActivedAt()
    {
        //获取今天的日期
        $date = Carbon::now()->toDateString();

        //Redis哈希表的命名, 如:larabbs_last_actived_at_2017-10-21
        $hash = $this->getHashFromDateString(Carbon::now()->toDateString());

        //字段命名user_id
        $field = $this->getHashField();

        //当前时间, 如: 2017-10-21 08:35:25
        $now = Carbon::now()->toDateTimeString();

        //数据写入Redis, 字段已存在会被更新
        Redis::hSet($hash, $field, $now);
    }

    public function syncUserActivedAt()
    {
        //获取昨天的日期, 格式如: 2017-10-21
        $yestoday_date = Carbon::now()->subDay()->toDateString();

        //Redis哈希表的命名, 如larabbs_last_Actived_at_2017-10-21
        $hash = $this->getHashFromDateString($yestoday_date);

        //从Redis中获取所有哈希表的数据
        $dates = Redis::hGetAll($hash);

        //遍历
        foreach ($dates as $user_id => $date) {
            $user_id = str_replace($this->field_prefix, '', $user_id);

            if ($user = $this->find($user_id)) {
                $user->last_actived_at = $date;
                $user->save();
            }
        }

        //以数据库为中心的存储, 即已同步, 即可删除
        Redis::del($hash);
    }

    public function getLastActivedAtAttribute($value)
    {
        //获取今日的日期
        $date = Carbon::now()->toDateString();

        //Redis哈希表命名, 如: larabbs_last_actived_at_2017-10-21
        $hash = $this->getHashFromDateString($date);

        //字段名称 如: user_id
        $field = $this->getHashField();

        //三元运算符, 优先考虑Redis,否则数据库
        $datetime = Redis::hGet($hash, $field) ?? $value;

        //如果存在的话,返回时间对应的Carbon实体
        if ($datetime) {
            return new Carbon($datetime);
        } else {
            //否则使用用户注册时间
            return $this->created_at;
        }
    }

    public function getHashFromDateString($date)
    {
        return $this->hash_prefix . $date;
    }

    public function getHashField()
    {
        return $this->field_prefix . $this->id;
    }
}
